package com.zrwl.poscloud.commons.utils;

/**
 * 
 * @author Administrator
 *		用机具的序列号进行加密
 */
public class SerialNoEncryUtil {

	public static String GetCryptionKey(String id){
		try{
			String ret="";
			int TmpCrc16;
			String crc=BanaryCrc16B(id);
			System.out.println("id:"+id);
//			System.out.println("crc16:"+crc);
			TmpCrc16= Integer.parseInt(crc, 16);
//			System.out.println("crcInt:"+TmpCrc16);
//			TmpCrc16=Integer.parseInt(BanaryCrc16B(id), 16);
			TmpCrc16=(TmpCrc16^ Integer.parseInt("F013", 16));
//			System.out.println("crc异或F013:"+TmpCrc16);
			String h= Integer.toHexString(TmpCrc16&255);
//			System.out.println("高位=crc异或异或255:"+h);
			String l= Integer.toHexString(TmpCrc16>>8);
//			System.out.println("低位=crc异或右移8位:"+l);
			h="00"+h;
			h=h.substring(h.length()-2);
			l="00"+l;
			l=l.substring(l.length()-2);
			ret=h+l;
//			ret="0000"+ret;
			ret=ret.substring(ret.length()-4);
			System.out.println("GetCryptionKey:"+ret);
			return ret;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	
	}
	private static String BanaryCrc16B(String s){
		String ret="";
		int  crc_h, crc_l ;
		int[] crcArrayH = new int[256] ;
		int[] crcArrayL = new int[256] ;
		
		String H= "0x01,0xc0,0xc1,0x01,0xc3,0x03,0x02,0xc2,0xc6,0x06,0x07,0xc7,0x05,0xc5,0xc4,0x04,"+
	            "0xcc,0x0c,0x0d,0xcd,0x0f,0xcf,0xce,0x0e,0x0a,0xca,0xcb,0x0b,0xc9,0x09,0x08,0xc8,"+
	            "0xd8,0x18,0x19,0xd9,0x1b,0xdb,0xda,0x1a,0x1e,0xde,0xdf,0x1f,0xdd,0x1d,0x1c,0xdc,"+
	            "0x14,0xd4,0xd5,0x15,0xd7,0x17,0x16,0xd6,0xd2,0x12,0x13,0xd3,0x11,0xd1,0xd0,0x10,"+
	            "0xf0,0x30,0x31,0xf1,0x33,0xf3,0xf2,0x32,0x36,0xf6,0xf7,0x37,0xf5,0x35,0x34,0xf4,"+
	            "0x3c,0xfc,0xfd,0x3d,0xff,0x3f,0x3e,0xfe,0xfa,0x3a,0x3b,0xfb,0x39,0xf9,0xf8,0x38,"+
	            "0x28,0xe8,0xe9,0x29,0xeb,0x2b,0x2a,0xea,0xee,0x2e,0x2f,0xef,0x2d,0xed,0xec,0x2c,"+
	            "0xe4,0x24,0x25,0xe5,0x27,0xe7,0xe6,0x26,0x22,0xe2,0xe3,0x23,0xe1,0x21,0x20,0xe0,"+
	            "0xa0,0x60,0x61,0xa1,0x63,0xa3,0xa2,0x62,0x66,0xa6,0xa7,0x67,0xa5,0x65,0x64,0xa4,"+
	            "0x6c,0xac,0xad,0x6d,0xaf,0x6f,0x6e,0xae,0xaa,0x6a,0x6b,0xab,0x69,0xa9,0xa8,0x68,"+
	            "0x78,0xb8,0xb9,0x79,0xbb,0x7b,0x7a,0xba,0xbe,0x7e,0x7f,0xbf,0x7d,0xbd,0xbc,0x7c,"+
	            "0xb4,0x74,0x75,0xb5,0x77,0xb7,0xb6,0x76,0x72,0xb2,0xb3,0x73,0xb1,0x71,0x70,0xb0,"+
	            "0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,"+
	            "0x9c,0x5c,0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,0x5a,0x9a,0x9b,0x5b,0x99,0x59,0x58,0x98,"+
	            "0x88,0x48,0x49,0x89,0x4b,0x8b,0x8a,0x4a,0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c,"+
	            "0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40,";
		String AH[]=H.split(",");

		String L  ="0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,"+
	            "0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,";

		String AL[]=L.split(",");
		for(int i=0;i<256;i++){
			crcArrayH[i]= Integer.parseInt(AH[i].substring(2), 16);
			crcArrayL[i]= Integer.parseInt(AL[i].substring(2), 16);
		}
		int i,l,iLen=0; //初始i=0
		crc_l=crc_h=255;; //高低位初始位
		iLen=s.length(); //得到字符串的长度
		for(l=0;l<iLen/2;l++){ //循环读取字符串，每两位读取一次
			int si= Integer.parseInt(s.substring(l*2,l*2+2),16);
			i=crc_l ^ si; //低位异或取得的两位字符串对应的整形值，赋予i ——   i := crc_l xor (StrToInt("$"+copy(s,l*2+1,2)));
			//i++;//i++  —— inc(i);
		    crc_l = crc_h ^crcArrayL[i]  ;//低位=高位异或i++，原算法是取自一个数组1-256 ——crc_l := crc_h xor crc16Blo[i]  ;
            crc_h =crcArrayH[i] ;//高位=i+1—— crc_h := crc16Bhi[i];
		}
		String hs="00"+ Integer.toHexString(crc_h);
		String ls="00"+ Integer.toHexString(crc_l);
		hs=hs.substring(hs.length()-2);
		ls=ls.substring(ls.length()-2);
		ret=hs+ls;//提取高位和低位对应的16进制字符串—— IntToHex(crc_h,2) + IntToHex(crc_l,2);
		return ret;
	}
	
	public static String DecryptEncryptBlock(String str, String onekey){
		String ret="";
		int []Tmpdata = new int[16],Tmpdest=new int[16];
		int H,L;
		H= Integer.parseInt(onekey.substring(0,2), 16);
		L= Integer.parseInt(onekey.substring(2), 16);
		for(int i=0;i<str.length()/2;i++){
			Tmpdata[i]= Integer.parseInt(str.substring(i*2,i*2+2), 16);
		}
		for(int i=0;i<str.length()/4;i++){
			Tmpdest[i*2]=Tmpdata[i*2] ^ H;
			Tmpdest[i*2+1]=Tmpdata[i*2+1] ^ L;
			String Hstr="00"+ Integer.toHexString(Tmpdest[i*2]);
			String Lstr="00"+ Integer.toHexString(Tmpdest[i*2+1]);
			Hstr=Hstr.substring(Hstr.length()-2);
			Lstr=Lstr.substring(Lstr.length()-2);
			ret+=(Hstr+Lstr);
		}
		System.out.println(ret);
		return ret;
	}
	public static void main(String[] args) {
		String onkey= GetCryptionKey("3233303131363437313334");//根据序列号生成密码
		DecryptEncryptBlock("FFFFFFFFFFFF",onkey);//用密码加密字符串
		DecryptEncryptBlock("0617",onkey);
		DecryptEncryptBlock("8888",onkey);
	}
}
